const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECT = "reject";
class MyPromise {
  #state = PENDING;
  #result = undefined;
  #handlers = [];
  constructor(executor) {
    const resolve = (result) => {
      this._changeState(FULFILLED, result);
    };
    const reject = (reason) => {
      this._changeState(REJECT, reason);
    };
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
  _changeState(state, result) {
    if (this.#state === PENDING) {
      this.#state = state;
      this.#result = result;
      console.log(this.#state, this.#result);
      this.#run();
    }
  }
  // 是否promise
  #isPromiseLike() {
    return false;
  }
  // 微任务
  #runMicroTask(fun) {
    setTimeout(fun, 0);
  }
  #runOne(callback, resolve, reject) {
    /* 
      1、callback不是回调函数
      2、callback是回调函数
      3、callback是promise
    */
    // console.log("run", this.#result);
    this.#runMicroTask(() => {
      // 不是一个函数，直接调用
      if (typeof callback !== "function") {
        const settled = this.#state === FULFILLED ? resolve : reject;
        settled(this.#result);
        return;
      }
      try {
        const data = callback(this.#result);
        // 判断返回是否promise
        if (this.#isPromiseLike(data)) {
          data.then(resolve, reject);
        } else {
          // 不是就直接调用
          resolve(data);
        }
      } catch (error) {
        // console.log("catch", error);
        reject(error);
      }
    });
  }
  #run() {
    if (this.#state === PENDING) {
      return;
    }
    // 循环多个事件 直至为空
    while (this.#handlers.length) {
      const { onFulfilled, onRejected, resolve, reject } =
        this.#handlers.shift();
      // 成功状态
      if (this.#state === FULFILLED) {
        this.#runOne(onFulfilled, resolve, reject);
      } else {
        // 失败状态
        this.#runOne(onRejected, resolve, reject);
      }
    }
  }
  // 接收两个参数
  then(onFulfilled, onRejected) {
    // then方法返回还是promise
    return new MyPromise((resolve, reject) => {
      // 处理异步问题，将所有数据存起来等状态变化再改变
      this.#handlers.push({
        onFulfilled,
        onRejected,
        resolve,
        reject,
      });
      this.#run();
    });
  }
}
const p = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(123);
  }, 1000);
});
p.then(
  (res) => {
    console.log("成功1", res);
  }, // null, // 当不是回调函数，和上一个promise结果和状态一样
  (err) => {
    console.log("失败1", err);
  }
)
  .then(
    (res) => {
      console.log("成功2", res);
      throw 456;
    },
    (err) => {
      console.log("失败2", err);
    }
  )
  .then(
    (res) => {
      console.log("成功3", res);
    },
    (err) => {
      console.log("失败3", err);
    }
  );
// p.then(
//   (res) => {
//     console.log("成功2", res);
//   },
//   (err) => {
//     console.log("失败2", err);
//   }
// );
// p.then(
//   (res) => {
//     console.log("成功3", res);
//   },
//   (err) => {
//     console.log("失败3", err);
//   }
// );
